#include <Precomp.h>
#include <XMLParser.h>

// Undef all of the overrides ogre has in place
#pragma warning(disable:4100)
#undef calloc
#undef free
#undef malloc
#undef realloc
typedef wchar_t WCHAR;
#import <msxml4.dll> raw_interfaces_only, no_smart_pointers
using namespace MSXML2;
using namespace AVUI;

class CSAXContentHandler : public ISAXContentHandler
{
public:
    CSAXContentHandler(IUIXMLContentHandler* pContentHandler) : m_pContentHandler(pContentHandler) { };
    virtual HRESULT STDMETHODCALLTYPE putDocumentLocator(ISAXLocator *pLocator)
    {
        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE startDocument(void)
    {
        m_pContentHandler->StartDocument();

        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE startElement(unsigned short *pwchNamespaceUri, int cchNamespaceUri, unsigned short *pwchLocalName, int cchLocalName, unsigned short *pwchQName, int cchQName, ISAXAttributes *pAttributes)
    {        
        m_pContentHandler->StartElement((WCHAR*)pwchLocalName, cchLocalName);

        int cAttributes;

        pAttributes->getLength(&cAttributes);

        for(int i = 0; i < cAttributes; i++)
        {
            unsigned short* pwchLocalName;
            int cchLocalName;
            unsigned short* pwchValue;
            int cchValue;

            pAttributes->getLocalName(i, &pwchLocalName, &cchLocalName);
            pAttributes->getValue(i, &pwchValue, &cchValue);

            m_pContentHandler->AddAttribute((WCHAR*)pwchLocalName, cchLocalName, (WCHAR*)pwchValue, cchValue);
        }

        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE endDocument(void)
    {
        m_pContentHandler->EndDocument();

        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE startPrefixMapping(unsigned short *pwchPrefix, int cchPrefix, unsigned short *pwchUri, int cchUri)
    {
        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE endPrefixMapping(unsigned short *pwchPrefix, int cchPrefix)
    {
        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE processingInstruction(unsigned short *pwchTarget, int cchTarget, unsigned short *pwchData, int cchData)
    {
        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE endElement(unsigned short *pwchNamespaceUri, int cchNamespaceUri, unsigned short *pwchLocalName, int cchLocalName, unsigned short *pwchQName, int cchQName)
    {
        m_pContentHandler->EndElement();

        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE characters(unsigned short *pwchChars, int cchChars)
    {
        m_pContentHandler->Characters((WCHAR*)pwchChars, cchChars);

        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE ignorableWhitespace(unsigned short *pwchChars, int cchChars)
    {
        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE skippedEntity(unsigned short *pwchName, int cchName)
    {
        return S_OK;
    }
    virtual ULONG STDMETHODCALLTYPE AddRef(void)
    {
        return 1;
    }
    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void * *ppvObject)
    {
        return S_OK;
    }
    virtual ULONG STDMETHODCALLTYPE Release(void)
    {
        return 1;
    }

private:
    IUIXMLContentHandler* m_pContentHandler;
};



void XMLParser::LoadXAML(IUIXMLContentHandler* pContentHandler, const WCHAR* wzFileName)
{
    ISAXXMLReader* pReader;

    CoCreateInstance(
            __uuidof(SAXXMLReader40), 
            NULL, 
            CLSCTX_ALL, 
            __uuidof(ISAXXMLReader), 
            (void **)&pReader);

    CSAXContentHandler saxContentHandler(pContentHandler);

    pReader->putContentHandler(&saxContentHandler);
    pReader->parseURL((unsigned short*)wzFileName);

    pReader->Release();
}

